﻿using System.Collections.Generic;
using Kyoh.Lib.Collections;

namespace Kyoh.Lib.IO.Tasks
{
    public partial class FileTaskProcessor<TProfile, TProcessor>
    {
        private class FileTaskQueue<T> : IEnumerable<FileTask<T>>
        {
            private ListedDictionary<string, FileTask<T>> targets = new ListedDictionary<string, FileTask<T>>();
            private readonly object locker = new object();
            public void Enqueue(FileTask<T> target)
            {
                lock (this.locker)
                {
                    if (!this.targets.ContainsKey(target.Path))
                    {
                        if (target.IsDirectory)
                            this.targets.Insert(0, target.Path, target);
                        else
                            this.targets.Add(target.Path, target);
                    }
                }
            }

            public FileTask<T> Dequeue()
            {
                lock (this.locker)
                {
                    try { return this.targets[0].Value; }
                    finally { this.targets.RemoveAt(0); }
                }
            }

            public int Count
            {
                get
                {
                    return this.targets.Count;
                }
            }

            public void Clear()
            {
                lock (this.locker)
                {
                    this.targets.Clear();
                }
            }

            public IEnumerator<FileTask<T>> GetEnumerator()
            {
                return new FileTaskEnumerator(this);
            }

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return new FileTaskEnumerator(this);
            }

            private class FileTaskEnumerator : IEnumerator<FileTask<T>>
            {

                private FileTaskQueue<T> queue;
                public FileTaskEnumerator(FileTaskQueue<T> queue)
                {
                    this.queue = queue;
                }

                public FileTask<T> Current
                {
                    get { return this.queue.Dequeue(); }
                }

                object System.Collections.IEnumerator.Current
                {
                    get { return this.queue.Dequeue(); }
                }

                public bool MoveNext()
                {
                    return this.queue.Count > 0;
                }

                public void Reset() { }

                public void Dispose()
                {
                    this.queue = null;
                }

            }

        }
    }
}